package com.example.shiro.intercept;

import com.example.shiro.utils.UserUtils;
import com.example.sys.authority.service.SysAuthorityService;
import com.example.sys.module.mode.SysModuleInfo;
import com.example.sys.module.service.SysModuleService;
import com.example.utils.StringUtils;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.subject.Subject;
import org.apache.shiro.web.filter.AccessControlFilter;
import org.apache.shiro.web.util.WebUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;

import javax.annotation.Resource;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;

public abstract class AbstractAccessControlFilter extends AccessControlFilter {

    Logger logger = LoggerFactory.getLogger(getClass());

    public static final String PREF = "/";
    public static final String ID = "id";

    @Value("${shiro.unauthorizedPath}")
    private String unauthorizedPath;

    @Resource
    private SysModuleService sysModuleService;

    @Resource
    private SysAuthorityService sysAuthorityService;

    @Override
    protected boolean onAccessDenied(ServletRequest servletRequest, ServletResponse servletResponse) throws Exception {
        return false;
    }

    public void redirectUnauthorized(ServletRequest servletRequest, ServletResponse servletResponse) throws Exception {
        WebUtils.issueRedirect(servletRequest, servletResponse, unauthorizedPath);
    }

    public SysModuleInfo getModuleByRequestUrl(ServletRequest servletRequest) {
        String requestURI = ((HttpServletRequest) servletRequest).getRequestURI();
        String[] split = requestURI.split(PREF);
        if (split != null && split.length > 2) {
            return this.sysModuleService.getSysModuleInfoByShortName(split[1]);
        }
        return null;
    }

    public Boolean validator(ServletRequest servletRequest, ServletResponse servletResponse, String roleAliases, int authType) throws Exception {
        Subject subject = SecurityUtils.getSubject();
        HttpServletRequest httpServletRequest = (HttpServletRequest) servletRequest;
        SysModuleInfo sysModuleInfo = this.getModuleByRequestUrl(servletRequest);
        if (sysModuleInfo != null && subject.isAuthenticated()) {
            String roleName = sysModuleInfo.getBaseRole() + roleAliases;
            if (UserUtils.getUser().getAuthRoleAliases().contains(roleName)) {
                return true;
            } else {
                String id = httpServletRequest.getParameter(ID);
                if (!StringUtils.isEmpty(id)) {
                    Boolean flag = sysAuthorityService.checkAuthority(UserUtils.getUser(), sysModuleInfo.getEntityClass().getName(), id, authType);
                    if (!flag) {
                        this.redirectUnauthorized(servletRequest, servletResponse);
                    }
                    return flag;
                }
            }
        }
        return true;
    }
}
